<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the 

  editor.
 */

class User extends AppModel {

    public $name = 'User';
    var $validate = array(
        'username' => array(
            'must enter user name' => array('rule' => 'notEmpty',
                'message' => 'please enter user name',
            ),
            'must be uniqe' => array('rule' => 'isUnique',
                'message' => 'This username already exists'),
            //minlength will be activated to be 3 later for easier testing
            'atleast 8 chars' => array('rule' => array('minLength', 1),
                'message' => 'Usernames must be at least 3 characters long.')
        ),
        'password' => array(
            'must enter password' => array(
                'rule' => 'notEmpty',
                'message' => 'please enter password',
            ),
            'minimum length 8' => array('rule' => array('minLength', 8),
                'message' => 'password must be at least 8 characters long.'),
            'matching Passwords' => array('rule' => 'matchPasswords',
                'message' => 'Your passwords do not match'
            )
        ),
        'fullname' => array(
            'must enter user name' => array('rule' => 'notEmpty',
                'message' => 'please enter the full mame'
            ),
            'must be uniqe' => array('rule' => 'isUnique',
                'message' => 'a user with this name already exists')
        ),
        'confirm password' => array(
            'must enter pw validation' => array('rule' => 'notEmpty',
                'message' => 'please enter password confirmation'
        )),
        'email' => array(
            'must enter user name' => array('rule' => 'notEmpty',
                'message' => 'please enter the E-mail'
            ),
            'must be uniqe' => array('rule' => 'isUnique',
                'message' => 'a user with this E-mail already exists'),
            'must be valid email' => array('rule' => 'email',
                'message' => 'Please Enter a Valid E-mail')
        )
    );

    /**
     * 
     * this method is used to encrypt the password of the user before adding it to the database
     * @author "Mohamed El-hawary"
     */
    public function beforeSave() {
        if (isset($this->data['User']['password'])) {
            $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
        }
        return true;
    }
	/**
     * this function sets the given user's accID field to the given $accID.
	 * @param $accID
	 * @param $user
     * @author "Omar Ruedy"
     */
    function updateUserWithAccId($user, $accID) {
        $this->updateAll(
                array('accID' => $accID), array('userID' => $user));
    }

    public function matchPasswords($data) {
        if ($data['password'] == $this->data['User']['confirm password']) {
            return true;
        }
        $this->invalidate('confirm password', 'Your passwords do not match');
        return false;
    }

    function getNames($ids = null) {
        if (sizeof($ids) != 0) {
            for ($i = 0; $i < sizeof($ids); $i++) {
                $result[$i] = $this->find('first', array('conditions' => array('userID' => $ids[$i]), 'fields' => array('fullname')));
            }
            return $result;
        }
        else
            return array();
    }

    function getUser($username) {

        return $this->find('all', array('conditions' => array('username' => $username), 'fields' => array('userID')));
    }

   function getUsers($accID, $userID) {
        return $this->query("SELECT users.username, users.image, users.facebook, users.twitter,users.userID
FROM accounts_has_users, users
WHERE users.userID = accounts_has_users.userID
AND users.deleted = 0
AND accounts_has_users.accID =" . $accID . " AND (accounts_has_users.permissionLevel = 1 OR accounts_has_users.permissionLevel = 2 or accounts_has_users.permissionLevel = 3) AND users.userID !=" . $userID);
    }
    /**
     * This method returns an array of users in a specific account
     *
     * @access: default
     * @param: int $accID; the accoutn id i need to get its users
     * @param: $user: a 3d array of users IDs
     *
     * @author "Mina Farag"
     */
    function getUser1($accID) {
        $user = $this->query("SELECT accounts_has_users.userID FROM accounts_has_users WHERE accounts_has_users.accID =" . $accID);
        if ($user == array()) {
            return 0;
        } else {
            return $user;
        }
    }

    /**
     * Description of "getUserID"
     * 
     * this function returns an array that contains the ID for the given username(USER)
	 *
	 * @param $username
	 * @return array 
	 *
	 * @author karim kamel
     */
    function getUserID($username) {
        return $this->find('all', array('conditions' => array('username' => $username), 'fields' => array('userID')));
    }

    /**
     * Description of "getUnassignedUsers"
     *
     * this function returns an array of all the unassigned users given an accID
	 *
	 * @param $accID
	 * @return array 
	 *
	 * @author karim kamel
     */
    function getUnassignedUsers($accID) {
        return $this->query("Select users.username from users where users.deleted = 0 AND users.admin = 0 AND
 not exists(select * from accounts_has_users where accounts_has_users.userID = users.userID AND
 accounts_has_users.accID = " . $accID . ")");
    }

    /**
     * Description of "getModeratorsByName" 
     * 
     * this function returns an array of all the moderators of a given accID
     *
	 * @param $accID
	 * @return array 
	 *
	 * @author karim kamel
     */
    function getModeratorsByName($accID) {
        return $this->query("SELECT users.username
FROM accounts_has_users, users
WHERE users.userID = accounts_has_users.userID
AND accounts_has_users.accID = " . $accID . " AND (accounts_has_users.permissionLevel = 3)");
    }

    /**
     * Description of "getEditorsByName"
	 *
     * this function returns an array of all the editorss of a given accID
	 *
     * @param $accID
	 * @return array 
	 *
	 * @author karim kamel
     */
    function getEditorsByName($accID) {
        return $this->query("SELECT users.username
FROM accounts_has_users, users
WHERE users.userID = accounts_has_users.userID
AND accounts_has_users.accID = " . $accID . " AND (accounts_has_users.permissionLevel = 2)");
    }

    /**
     * Description of "getJEditorsByName" 
     * 
     * this function returns an array of all the jEditors of a given accID
     *
     * @param $accID
	 * @return array 
	 *
	 * @author karim kamel
     */
    function getJEditorsByName($accID) {
        return $this->query("SELECT users.username
FROM accounts_has_users, users
WHERE users.userID = accounts_has_users.userID
AND accounts_has_users.accID = " . $accID . " AND (accounts_has_users.permissionLevel = 1)");
    }

    /**
     * This method returns an array of all undeleted users in the system 
     *
     * @access: public
     * 
     * 
     *
     * @author "Mina Farag"
     */
    public function getAllUsers() {
        return( $this->find('all', array('conditions' => array('deleted' => 0, 'admin' => 0), 'fields' => array('username', 'userID','image'))));
    }

    /**
     * This method returns the permission level of a specific user in a specicfic account
     *
     * @access: default
     * @param: int $accID; the account id i need to get the permission level from
     * @param: int $userID; the user i need to get his permission level
     * @param: array $permission; a 3D array of one record which is the permission level 
     *
     * @author "Mina Farag"
     */
    function getPermissionLevel($accID, $userID) {
        //select the permission level of the account and user id from table accounts_has_users
        $permission = $this->query("Select permissionLevel from Accounts_has_users where accounts_has_users.userID =" . $userID . " AND accounts_has_users.accID = " . $accID);
        // if the account and user id combination does not exist return 0 
        if ($permission == array()) {
            return 0;
        } else {
            return $permission[0]['Accounts_has_users']['permissionLevel'];
        }
    }

    function getTweetAuthor($authorID) {

        return $this->find('all', array('conditions' => array('userID' => $authorID), 'fields' => array('username', 'image')));
    }

    /**
     * This method returns 1 if the user is an admin and 0 if he is not 
     *
     * @access: default
     * @param: int $userID; the user id i want to know wheter he is an admin or not
     * @param: array $admin; 3d array of the admin record of the user from the Users table
     *
     * @author "Mina Farag"
     */
    function isAdmin($userID) {
        $admin = $this->find('all', array('conditions' => array('userID' => $userID), 'fields' => array('admin')));
        return $admin[0]['User']['admin'];
    }

    /**
     * This method deletes a certain user from the system 
     *
     * @access: default
     * @param: int $callerID; the user id of the caller of the method
     * @param: int $userID; the user i need to delete
     * @param: int $callerAdmin; is the admin record of the caller of the method from users table  
     * @param: array $deleted; is 3d array of the deleted record of the user i want to delete
     * @author "Mina Farag"
     */
    function deleteUser($callerID, $userID) {
        $callerAdmin = $this->isAdmin($callerID);
        $deleted = $this->find('all', array('conditions' => array('userID' => $userID), 'fields' => array('deleted')));
        //checks if the caller is an admin 
        if ($callerAdmin == 1) {
            //admin cannot delete himself
            if ($callerID == $userID) {
                return "admin cannot delete himself";
                //cannot delete an already deleted user
            } elseif ($deleted[0]['User']['deleted'] == 1) {
                return "the user is already deleted";
            } else {
                //set the delete record to 1
                $this->updateAll(
                        array('deleted' => 1), array('userID' => $userID));
                //delete the user of all the assigned accounts
                $this->query("DELETE FROM Accounts_has_users WHERE accounts_has_users.userID=" . $userID);
                return "the user was deleted successfuly";
            }
        } else {
            return "this command needs an admin permission";
        }
    }

    function getUserName($userID) {
        return $this->find('all', array('conditions' => array('userID' => $userID), 'fields' => array('username')));
    }

    /**
     * @author Amr Magdy
     * @return array  
     * 
     * this function returns an array of all the editors of a given accID and their user ids
     */
    function getEditorsByNameandid($accID) {
        return $this->query("SELECT users.username , users.userID
		FROM accounts_has_users, users
		WHERE users.userID = accounts_has_users.userID
		AND accounts_has_users.accID = " . $accID . " AND (accounts_has_users.permissionLevel = 2)");
    }

    /**
     * @author Amr Magdy
     * @return array  
     * 
     * this function returns an array of all the J.editors of a given accID and their user ids
     */
    function getJEditorsByNameandid($accID) {
        return $this->query("SELECT users.username ,  users.userID
		FROM accounts_has_users, users
		WHERE users.userID = accounts_has_users.userID
		AND accounts_has_users.accID = " . $accID . " AND (accounts_has_users.permissionLevel = 1)");
    }
	

    /**
     * This method returns an array of all deleted users in the system 
     *
     * @access: public
     * 
     * 
     *
     * @author "Mina Farag"
     */
    public function getDeletedUsers() {
        return( $this->find('all', array('conditions' => array('deleted' => 1, 'admin' => 0), 'fields' => array('username', 'userID','image'))));
    }
	  function getDeleted($userID)
    {
                $user =  $this->find('all', array('conditions' => array('userID' => $userID), 'fields' => array('deleted')));
                return $user[0]['User']['deleted'];
    }

    /**
     * This method restores a deleted user back to the system 
     *
     * @access: default
     * @param: int $callerID; the user id of the caller of the method
     * @param: int $userID; the user i need to restore
     * @param: int $callerAdmin; is the admin record of the caller of the method from users table  
     * @param: array $deleted; is 3d array of the deleted record of the user i want to delete
     * @author "Mina Farag"
     * the function checks if the caller is an admin and then if the user is not deleted 
     * if the these two checks are positive then it restores the user back to the system 
     */
    function restoreUser($callerID, $userID) {
        $callerAdmin = $this->isAdmin($callerID);
        $deleted = $this->find('all', array('conditions' => array('userID' => $userID), 'fields' => array('deleted')));
        //checks if the caller is an admin 
        if ($callerAdmin == 1) {
            //checks if the user is not deleted

            if ($deleted[0]['User']['deleted'] == 0) {
                return "the user is not deleted";
            }
            //restore the user
            $this->updateAll(
                    array('deleted' => 0), array('userID' => $userID));
            return "the user was restored successfuly";
        }
        return "this command needs an admin permission";
    }
	
	/**
     * Descriotion of viewUsers($userID, $accID):
     * @param $userID, $accID
     * @return array of users
     * @access public
     * 
     * Description of the function:
     * A function taking userID, accountID as Input and returns list of existing users for the same acc 
     * @author "OmarElshal"
     */
    function viewUsers($userID, $accID) {


        $count = $this->find('count');
        if ($count != 0) {
            $users['joins'] = array(
                array(
                    'table' => 'accounts_has_users',
                    'alias' => 'Acc',
                    'type' => 'INNER',
                    'conditions' => array('User.userID =  Acc.userID', 'Acc.accID' => $accID, 'User.userID' != $userID
                        , ('Acc.permissionLevel = 1' OR 'Acc.permissionLevel = 2' OR 'Acc.permissionLevel = 3'))
                )
            );

            $result = $this->find('all', $users);
            return $result;
        }
        else
            return 0;
    }
    
    /**
     * This method returns the new password randomly generated after being inserted in the database for a specific user
     *
     * @access: default
     * @param: int $len; the length of the required password
     * @param: String $userID; the user i need to give him this new password
     * @param: String $password; the hashed password inserted in the database
     * @param: String $pass;is the password returned and sent to the user 
     * @return: String $pass;
     * the method generates a random password then this password is hashed
     * and inserted into the password record of the database corresponding to this 
     * specific user and then the unhashed password os returned  
     * @author "Mina Farag"
     */
    
    function createTempPassword($len,$userID) { 
                $pass = ''; 
                $lchar = 0; 
                $char = 0; 
                for($i = 0; $i < $len; $i++) { 
                        while($char == $lchar) { 
                                $char = rand(48, 109); 
                                if($char > 57) $char += 7; 
                                if($char > 90) $char += 6; 
                        } 
                        $pass .= chr($char); 
                        $lchar = $char; 
                } 
              $password= AuthComponent::password($pass);
                $this->updateAll(
                    array('password' => "'$password'"), array('userID' => $userID));
                return $pass; 
        } 
        
        /**
     *@author Moataz Ezzo
     *This function get the data of a specific user from the database
     */
    function getProfile($userID) {
        return $this->query("SELECT users.fullname, users.image, users.email, 
FROM accounts_has_users, users
WHERE users.userID = ". $userID . "AND (users.deleted = 0)" );
    }



}

?>